

import sys
import os
import commands
import netaddr

from cfcall.deploy_plugin import deploybase

class AttributeDict(dict): 
    __getattr__ = dict.__getitem__
    __setattr__ = dict.__setitem__

class deployCobblerUBUNTU(deploybase.depBase):
    """A auto deploy system for bear metal machine.

    Cobbler will open dhcp/tftp/pxe env on a machine.
    """
    ubuntu12lts='http://archive.ubuntu.com/ubuntu/dists/precise/main/installer-i386/current/images/netboot/mini.iso'
    ubuntu14lts='http://archive.ubuntu.com/ubuntu/dists/precise/main/installer-amd64/current/images/netboot/mini.iso'

    DISTs = ['Ubuntu',]
    PKGs = [
            #depdency
            'ethtool',
            # cobbler env
            'cobbler',
            'cobbler-web',
            'debmirror',
            'createrepo',
            'isc-dhcp-server',
            'bind9',
            'dhcping',
            ]
    rm_PKGs = [
               'cobbler',
               'cobbler-web',
              ] 
    cfg = AttributeDict( 
            desc="""Dual eth0 machine for product and Operation.

             eth0: connect to internet or cloud management 
             eth1: provide Cobbler service:pxe, dhcp, tftp and router.
                    
            """,
            cob_set_file = '/etc/cobbler/settings',
            cob_mod_file = '/etc/cobbler/modules.conf',
            cob_dhcp_file = '/etc/cobbler/dhcp.template',
            cob_dhcp_env_file='/etc/default/isc-dhcp-server',
            cob_bind_file='/etc/cobbler/named.template',
            
            cob_eth='eth1',
            cob_eth_ip='192.168.253.1/24',
            cob_routers ='192.168.253.1',
            cob_dns_server='8.8.8.8',
            iso = ubuntu14lts,
            
            distro = [
                      AttributeDict(name='ubuntu12.04-mini-lts',
                                    iso=ubuntu12lts,
                                    arch='x86_64',
                                    ),
                      ]
          )
       
                                    
    def _purge_cobbler_distro(self):
        dists = self._run_cmd('sudo cobbler profile list')
        for dist in dists.splitlines():
            cmd = 'sudo cobbler profile remove --name %s'%dist
            self._run_cmd(cmd)
        dists = self._run_cmd('sudo cobbler distro list')
        for dist in dists.splitlines():
            cmd = 'sudo cobbler distro remove --name %s'%dist
            print cmd
            self._run_cmd(cmd)

    # install/deploy/undeploy/showcfg
    def deploy(self, args):
	try:
	    self._purge_cobbler_distro()
        except:
	    print "skip purge cobber setting"
        cobip = netaddr.IPNetwork(self.cfg.cob_eth_ip)
        
        print "==================="
        # config cobbler eth ip
        print "Attach Cobbler IP address %s to %s"%(self.cfg.cob_eth_ip,self.cfg.cob_eth)
        self._run_cmd("sudo ifconfig %s %s netmask %s up"%
                      (self.cfg.cob_eth, cobip.ip,cobip.netmask))
        
        # config it management dhcp/dns/tftp
        cf = self.cfg.cob_set_file
        self._cfg(cf, 'manage_dhcp', '1')
        self._cfg(cf, 'manage_dns', '1')
        self._cfg(cf, 'manage_tftpd', '1')
        self._cfg(cf, 'manage_rsync', '1')
        
        cf = self.cfg.cob_mod_file
        cmd=r"""sudo sed -i  '/\[tag\]/I{n;"""+\
            r"""s/\(module *= *\)*.*/\1value/ }' %s"""%cf
        self._run_cmd(cmd.replace('tag','dns').replace('value', 'manage_bind'))
        self._run_cmd(cmd.replace('tag','dhcp').replace('value', 'manage_isc'))
        self._run_cmd(cmd.replace('tag','tftpd').replace('value', 'manage_in_tftpd'))
        
        #config dhcp so the dhcp server will only response to this interface
        cf = self.cfg.cob_dhcp_env_file
        self._cfg(cf, 'INTERFACES','"%s"'%self.cfg.cob_eth, sep="=")
        
        cf = self.cfg.cob_dhcp_file
        cmd=r"""sudo sed -i 's/\(subnet *\)ip\( *netmask *\)ip\(.*\)/\1%s\2%s\3/' %s"""
        cmd = cmd.replace('ip','[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' )
        cmd = cmd%(cobip.network,cobip.netmask,cf)
        print cmd
        self._run_cmd(cmd)
        self._cfg(cf, 'option', self.cfg.cob_routers+";", sep="routers")
        self._cfg(cf, 'option', self.cfg.cob_dns_server+";", sep="domain-name-servers")
        self._cfg(cf, 'option', str(cobip.netmask)+";", sep="subnet-mask")
        self._cfg(cf, 'range',  str(cobip.ip+50)+" "+str(cobip.ip+100)+";", sep="dynamic-bootp")
        
        #config dhcp so the dhcp server will only response to this interface
        cf = self.cfg.cob_set_file
        self._cfg(cf, 'bind_master', cobip.ip)
        self._cfg(cf, 'server', cobip.ip)
        self._cfg(cf, 'next_server', cobip.ip)

        # config bind listen on only the specify interface
        cf = self.cfg.cob_bind_file
        status,output = commands.getstatusoutput('sudo grep "options {" %s'%cf)
        if status != 0:
            pat = r"""#for \$zone in \$forward_zones"""
            cmd=r"""sudo sed -i '/%s/i\options {\nlisten-on { %s; };\n};' %s"""%(pat,cobip.ip,cf)
            out = self._run_cmd(cmd)

        #pull minimal ISO
        try:
            for dist in self.cfg.distro:
                os.system('wget -N -P /tmp/ %s'%dist.iso)
                os.system('sudo mount -o loop /tmp/%s /mnt'%(dist.iso.split('/')[-1]))
                os.system('sudo cobbler import --name=%s --path=/mnt --arch %s'%
                                    (dist.name, dist.arch))
                os.system('sudo umount /mnt')
        except Exception as e:
            os.system('sudo umount /mnt')
            raise e
        
        self._run_cmd("sudo cobbler sync")
        
        # restart service 
        self._run_cmd("sudo service apache2 restart")
        self._run_cmd("sudo service bind9 restart")
        self._run_cmd("sudo service tftpd-hpa restart")
        self._run_cmd("sudo service isc-dhcp-server restart")
        print "==================="
        self.check(args)
       

    def check(self, args):
        cobip = netaddr.IPNetwork(self.cfg.cob_eth_ip)
         
        print "*****Checking service status:"
        print "    ",self._run_cmd("service bind9 status")
        print "    ",self._run_cmd("service apache2 status")
        print "    ",self._run_cmd("sudo service tftpd-hpa status")
        print "    ",self._run_cmd("sudo service isc-dhcp-server status")
        print "*****Checking Cobbler, Cobbler_web response:"
        status = self._cmd_grep("curl -I 127.0.0.1/cobbler_web", 'HTTP/1.1 200 OK')
        print "    ",status
        status = self._cmd_grep("curl -I 127.0.0.1/cobbler/", 'HTTP/1.1 200 OK')
        print "    ", status
        
        print "****Checking port status:"
        ckcmd = r"""sudo netstat -tunlp | grep LISTEN | grep "%s" | grep "%s" """
        ckcmd2 = r"""sudo netstat -tunlp | grep "%s" | grep "%s" """
        print  "WEB server :", self._run_cmd(ckcmd%('apache2', ':80'))
        print  "DNS        :", self._run_cmd(ckcmd%('named', ':53'))
        print  "DHCP       :", self._run_cmd(ckcmd2%('dhcpd', ':67'))
        print  "TFTP       :", self._run_cmd(ckcmd2%('in.tftpd', ':69'))
        print  "COBBER WEB :", self._run_cmd(ckcmd%('python', '25151'))

    
        print "****Checking cobbler interface:",self._cmd_grep("sudo ethtool %s"%self.cfg.cob_eth,
                                                               'Link detected:')

    def stop(self, args):
        self._run_cmd("sudo service bind9 stop")
        self._run_cmd("sudo service tftpd-hpa stop")
        self._run_cmd("sudo service isc-dhcp-server stop")

    def fix(self, args):
        print "=====trying recovery apache Cobbler configration"
        self._run_cmd("sudo apt-get remove isc-dhcp-server cobbler-common cobbler cobbler-web apache2"
                      " libapache2-mod-wsgi libapache2-mod-python --purge -y -f")
        self.install(args)
        self.deploy(args)




